package com.dragon.logical.service.contract.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.common.model.ResultCode;
import com.dragon.common.model.exception.CustomException;
import com.dragon.common.util.DateNumUtils;
import com.dragon.logical.service.contract.ContractService;
import com.dragon.logical.service.contract.IRejectedService;
import com.dragon.logical.service.customer.CustomerService;
import com.dragon.logical.service.customer.QuotesService;
import com.dragon.repository.entity.*;
import com.dragon.repository.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * <p>
 * 合同表 服务实现类
 * </p>
 *
 * @author sy
 * @since 2023-06-21
 */
@Service
public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract> implements ContractService {

    @Autowired
    ContractMapper mapper;
    @Autowired
    ContractArticleSonMapper casMapper;
    @Autowired
    ContractArticleMapper articleMapper;
    @Autowired
    CustomerMapper customerMapper;
    @Autowired
    QuotesMapper quotesMapper;
    @Autowired
    QuotesProductsMapper quotesProductsMapper;
    @Autowired
    AdminMapper adminMapper;
    @Autowired
    ProduceMapper produceMapper;
    @Autowired
    PlanCollectMapper planCollectMapper;
    @Autowired
    OtherFileMapper otherFileMapper;
    @Autowired
    ProduceProductsMapper produceProductsMapper;
    @Autowired
    AdminDepartmentMapper adminDepartmentMapper;
    @Autowired
    DeliverMapper deliverMapper;
    @Autowired
    CustomerPaymentMapper paymentMapper;
    @Autowired
    QuotesService quotesService;
    @Autowired
    ContractFitMapper fitMapper;
    @Autowired
    ExamineMapper examineMapper;
    @Autowired
    CustomerService customerService;
    @Autowired
    ProduceSchedulingMapper produceSchedulingMapper;
    @Autowired
    SchedulingSonMapper schedulingSonMapper;
    @Autowired
    RejectedMapper rejectedMapper;
    @Autowired
    IRejectedService rejectedService;
    @Autowired
    RepairMapper repairMapper;


    @Override
    public Page<Contract> contractList(Integer page, Integer limit, String search, Integer status, Integer applicationId, String startTime, String endTime, Integer customerId) {
        Page<Contract> contractPage = new Page<>(page, limit);
        QueryWrapper<Contract> wrapper = new QueryWrapper<>();
            if (StrUtil.isBlank(endTime)) {
                endTime = DateUtil.date().toString();
            }
            if (StrUtil.isBlank(startTime)) {
                startTime = "1999-01-01";
            }
        wrapper
                .eq("a.deleted",0)
                .like(StrUtil.isNotBlank(search), "a.name", search)
                .eq(status != null, "a.status", status)
                .ne("a.status",3)
                .eq(applicationId != null, "a.admin_id", applicationId)
                .eq(customerId != null, "a.customer_id", customerId)
                .ge(StrUtil.isNotBlank(startTime), "a.create_time", DateUtil.parse(startTime, "yyyy-MM-dd"))
                .le(StrUtil.isNotBlank(endTime), "a.create_time", DateUtil.offsetDay(DateUtil.parse(endTime, "yyyy-MM-dd"),1));
        Page<Contract> contractList = mapper.contractList(contractPage, wrapper);
        return contractList;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public AddPageData addContract(Contract contract) {
        AtomicReference<Boolean> isAudit = new AtomicReference<>(false);
        if (contract.getWorkflowJsonList() != null && contract.getWorkflowJsonList().size() != 0) {
            contract.getWorkflowJsonList().forEach(workflowJson -> {
                if (workflowJson.getType() == 1) {
                    isAudit.set(true);
                }
            });
        }
        contract.setCreateTime(DateUtil.date());
        //获取 供应商的首字母
        ContractFit contractFit = fitMapper.selectOne(new QueryWrapper<ContractFit>().lambda()
                .eq(ContractFit::getPartyBName, contract.getPartyBName()));
        //自动生成编号
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String code = contractFit.getCodeLetter()+"_"+ sdf.format(contract.getCreateTime());
        String maxCode =  mapper.maxRoundInoutNumber(code);
        String newCode = null;
        if (StrUtil.isEmpty(maxCode)){
            newCode = code + "001";
        }
        else {
            String getMaxCode = maxCode.substring(maxCode.length()-3, maxCode.length());
            newCode = code + DateNumUtils.getNum(getMaxCode);
        }
        contract.setNum(newCode);
        contract.setStatus(isAudit.get() == true ? 0 : 1);
        contract.setQuotesId(contract.getQuotesData().getId());
        contract.setCustomerId(contract.getQuotesData().getCustomerId());
        mapper.insert(contract);
        // 条款
        ContractArticle articleList = contract.getArticleList();
        if (articleList.getId() != null) {
            ContractArticle article = articleMapper.selectById(articleList.getId());
            ContractArticleSon son = new ContractArticleSon();
            son.setContractId(contract.getId());
            son.setArticleId(article.getId());
            casMapper.insert(son);
            contract.setLessorArticle(article.getArticleText());
            contract.setLessorArticleTitle(article.getArticleTitle());
            mapper.updateById(contract);
        }
        //附件
        if (contract.getOtherFiles() != null) {
            contract.getOtherFiles().forEach(e -> {
                e.setCreateTime(DateUtil.date());
                e.setCorrelationId(contract.getId());
                e.setStreamType(2);
                otherFileMapper.insert(e);
            });
        }


        /**
         * 修改单子是否关联合同
         */
        Quotes quotes = quotesMapper.selectById(contract.getQuotesId());
        quotes.setIsContract(1);
        quotesMapper.updateById(quotes);

        //生成必要单子
        if (!isAudit.get()) {
            generateList(contract);
        }

        AddPageData addPageData = new AddPageData();
        addPageData.setAdminId(contract.getAdminId());
        addPageData.setCorrelationId(contract.getId());
        addPageData.setWorkflowJson(contract.getWorkflowJsonList());
        addPageData.setStreamType(2);
        addPageData.setTitle(contract.getName());
        addPageData.setExempt(contract.getExempt());
        return addPageData;
    }

    @Override
    public void generateList(Contract contract){
        QueryWrapper<AdminDepartment> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(AdminDepartment::getAdminId,contract.getPayee(),contract.getProductionPerson());
        List<AdminDepartment> adminDepartment = adminDepartmentMapper.selectList(queryWrapper);
        Integer payee = adminDepartment.stream().filter(e->e.getAdminId().equals(contract.getPayee())).findFirst().get().getDepartmentId();
        Integer productionPerson = adminDepartment.stream().filter(e->e.getAdminId().equals(contract.getProductionPerson())).findFirst().get().getDepartmentId();
        String code, maxCode,newCode = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        // 现结
//        if(contract.getSettlement() == 1){
        // 是否是3d打印建模合同，如果是则直接生成应收账单
        if(contract.getModeling() == 0){
            switch (contract.getPaymentMethod()) {
                //预付款，生成预付款计划回款 t + 1 -> 生成生产单 ->计划回款和
                case 1:
                    PlanCollect planCollect = new PlanCollect();
                    planCollect.setContractId(contract.getId());
                    planCollect.setCustomerId(contract.getCustomerId());
                    planCollect.setCreateTime(DateUtil.date());
                    planCollect.setAdminId(contract.getPayee());
                    planCollect.setDepartmentId(payee);
                    planCollect.setPlanMoney(contract.getPrepaymentMoney());
                    planCollect.setPlanPayType(contract.getCombination() == null ? 0 : 1);
                    // t + 2
                    planCollect.setPlanTime(DateUtil.offsetDay(DateUtil.date(),2));
                    planCollectMapper.insert(planCollect);
                    break;
                //到付，生成生产单->生成配送单->生成回款计划t+1
                case 2:
                    //生成生产单
                    Produce produce = new Produce();
                    produce.setCreateTime(DateUtil.date());
                    //自动生成编号
                    //SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
                    code = "SC-" + sdf.format(produce.getCreateTime());
                    maxCode =  produceMapper.maxRoundInoutNumber(code);
                    //String newCode = null;
                    if (StrUtil.isEmpty(maxCode)){
                        newCode = code + "001";
                    }
                    else {
                        String getMaxCode = maxCode.substring(11, 14);
                        newCode = code + DateNumUtils.getNum(getMaxCode);
                    }
                    produce.setNumber(newCode);
                    //produce.setName(contract.getName().concat("-生产单"));
                    produce.setContractId(contract.getId());
                    produce.setAdminId(contract.getAdminId());
                    produce.setDepartmentId(productionPerson);
                    produce.setResponsibleId(contract.getProductionPerson());
                    produce.setStatus(1);
                    produce.setEndTime(contract.getEndTime());
                    produce.setDeliveryTime(contract.getDeliveryTime());
                    produceMapper.insert(produce);
                    //生产生产单关联表
                    QueryWrapper<QuotesProducts> productsQueryWrapper = new QueryWrapper<>();
                    productsQueryWrapper.lambda().eq(QuotesProducts::getQuotesId,contract.getQuotesId());
                    List<QuotesProducts> quotesProducts = quotesProductsMapper.selectList(productsQueryWrapper);
                    // 插入报价单子到生产单中
                    if(quotesProducts==null&&quotesProducts.size()==0){
                        throw new CustomException(ResultCode.PARAM_IS_BLANK);
                    }

                    quotesProducts.forEach(quotesProducts3 -> {
                        ProduceProducts produceProducts = new ProduceProducts();
                        produceProducts.setProduceId(produce.getId());
                        produceProducts.setQuotesProductId(quotesProducts3.getProductsId());
                        produceProducts.setNum(quotesProducts3.getNum());
                        produceProducts.setProduceStatus(0);
                        produceProductsMapper.insert(produceProducts);
                    });
                    break;
                // 约定时间，计划回款,生产单->配送单
                case 3:
                    // 计划回款
                    PlanCollect planCollect1 = new PlanCollect();
                    planCollect1.setContractId(contract.getId());
                    planCollect1.setCustomerId(contract.getCustomerId());
                    planCollect1.setCreateTime(DateUtil.date());
                    planCollect1.setAdminId(contract.getPayee());
                    planCollect1.setDepartmentId(payee);
                    planCollect1.setActualPlanMoney(0.00);
                    planCollect1.setPlanMoney(contract.getMoney());
                    //约定时间
                    planCollect1.setPlanTime(contract.getAgreeTime());
                    planCollectMapper.insert(planCollect1);
                    //生成生产单
                    Produce produce1 = new Produce();
                    produce1.setCreateTime(DateUtil.date());

                    //自动生成编号
                    code = "SC-" + sdf.format(produce1.getCreateTime());
                    maxCode =  produceMapper.maxRoundInoutNumber(code);
                    //String newCode = null;
                    if (StrUtil.isEmpty(maxCode)){
                        newCode = code + "001";
                    }
                    else {
                        String getMaxCode = maxCode.substring(11, 14);
                        newCode = code + DateNumUtils.getNum(getMaxCode);
                    }
                    produce1.setNumber(newCode);

                    //produce1.setName(contract.getName().concat("-生产单"));
                    produce1.setContractId(contract.getId());
                    produce1.setAdminId(contract.getAdminId());
                    produce1.setDepartmentId(productionPerson);
                    produce1.setResponsibleId(contract.getProductionPerson());
                    produce1.setStatus(1);
                    produce1.setEndTime(contract.getEndTime());
                    produceMapper.insert(produce1);
                    //生产生产单关联表
                    QueryWrapper<QuotesProducts> productsQueryWrapper1 = new QueryWrapper<>();
                    productsQueryWrapper1.lambda().eq(QuotesProducts::getQuotesId,contract.getQuotesId());
                    List<QuotesProducts> quotesProducts1 = quotesProductsMapper.selectList(productsQueryWrapper1);
                    // 插入报价单子到生产单中
                    if(quotesProducts1==null&&quotesProducts1.size()==0){
                        throw new CustomException(ResultCode.PARAM_IS_BLANK);
                    }
                    quotesProducts1.forEach(quotesProducts2 -> {
                        ProduceProducts produceProducts1 = new ProduceProducts();
                        produceProducts1.setProduceId(produce1.getId());
                        produceProducts1.setQuotesProductId(quotesProducts2.getProductsId());
                        produceProducts1.setNum(quotesProducts2.getNum());
                        produceProducts1.setProduceStatus(0);
                        produceProductsMapper.insert(produceProducts1);
                    });
                    break;
                default:
                    break;
            }
        } else {
            switch (contract.getPaymentMethod()) {
                // 预付款
                case 1:
                    PlanCollect planCollect = new PlanCollect();
                    planCollect.setContractId(contract.getId());
                    planCollect.setCustomerId(contract.getCustomerId());
                    planCollect.setCreateTime(DateUtil.date());
                    planCollect.setAdminId(contract.getPayee());
                    planCollect.setDepartmentId(payee);
                    planCollect.setPlanMoney(contract.getPrepaymentMoney());
                    //预付款
                    planCollect.setPlanPayType(contract.getCombination() == null ? 0 : 1);
                    // t + 2
                    planCollect.setPlanTime(DateUtil.offsetDay(DateUtil.date(),2));
                    planCollectMapper.insert(planCollect);
                    break;
                    // 到付
                case 2:
                    // 计划回款
                    PlanCollect planCollect2 = new PlanCollect();
                    planCollect2.setContractId(contract.getId());
                    planCollect2.setCustomerId(contract.getCustomerId());
                    planCollect2.setCreateTime(DateUtil.date());
                    planCollect2.setAdminId(contract.getPayee());
                    planCollect2.setDepartmentId(payee);
                    planCollect2.setActualPlanMoney(0.00);
                    planCollect2.setPlanMoney(contract.getMoney());
                    //直接当前时间，生成对账单
                    planCollect2.setPlanTime(DateUtil.offsetDay(DateUtil.date(),2));
                    planCollectMapper.insert(planCollect2);
                    break;
                    // 约定时间付款
                case 3:
                    // 计划回款
                    PlanCollect planCollect1 = new PlanCollect();
                    planCollect1.setContractId(contract.getId());
                    planCollect1.setCustomerId(contract.getCustomerId());
                    planCollect1.setCreateTime(DateUtil.date());
                    planCollect1.setAdminId(contract.getPayee());
                    planCollect1.setDepartmentId(payee);
                    planCollect1.setActualPlanMoney(0.00);
                    planCollect1.setPlanMoney(contract.getMoney());
                    //约定时间
                    planCollect1.setPlanTime(contract.getAgreeTime());
                    planCollectMapper.insert(planCollect1);
                    break;
            }
        }
//        } else {
//            /*月结*/
//            //生成生产单
//            Produce produce = new Produce();
//            produce.setCreateTime(DateUtil.date());
//            //自动生成编号
//            //SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
//            code = "SC-" + sdf.format(produce.getCreateTime());
//            maxCode =  produceMapper.maxRoundInoutNumber(code);
//            //String newCode = null;
//            if (StrUtil.isEmpty(maxCode)){
//                newCode = code + "001";
//            }
//            else {
//                String getMaxCode = maxCode.substring(11, 14);
//                newCode = code + DateNumUtils.getNum(getMaxCode);
//            }
//            produce.setNumber(newCode);
//            //produce.setName(contract.getName().concat("-生产单"));
//            produce.setContractId(contract.getId());
//            produce.setAdminId(contract.getAdminId());
//            produce.setDepartmentId(productionPerson);
//            produce.setResponsibleId(contract.getProductionPerson());
//            produce.setStatus(1);
//            produce.setEndTime(contract.getEndTime());
//            produce.setDeliveryTime(contract.getDeliveryTime());
//            produceMapper.insert(produce);
//            //生产生产单关联表
//            QueryWrapper<QuotesProducts> productsQueryWrapper = new QueryWrapper<>();
//            productsQueryWrapper.lambda().eq(QuotesProducts::getQuotesId,contract.getQuotesId());
//            List<QuotesProducts> quotesProducts = quotesProductsMapper.selectList(productsQueryWrapper);
//            // 插入报价单子到生产单中
//            if(quotesProducts==null&&quotesProducts.size()==0){
//                throw new CustomException(ResultCode.PARAM_IS_BLANK);
//            }
//            quotesProducts.forEach(quotesProducts3 -> {
//                ProduceProducts produceProducts = new ProduceProducts();
//                produceProducts.setProduceId(produce.getId());
//                produceProducts.setQuotesProductId(quotesProducts3.getProductsId());
//                produceProducts.setNum(quotesProducts3.getNum());
//                produceProducts.setProduceStatus(0);
//                produceProductsMapper.insert(produceProducts);
//            });
//        }
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void updateContract(Contract contract) {
        Contract one = mapper.selectOneById(contract.getId());
        if (one == null) {
            throw new CustomException(ResultCode.CONTRACT_DATA_NOT_FOUND);
        }

        // 不做任何更改
        if(!contract.getQuotesId().equals(one.getQuotesId())){

            Quotes quotes = quotesMapper.selectById(one.getQuotesId());
            quotes.setIsContract(1);
            quotesMapper.updateById(quotes);
        }

        //查看 修改后的合同有没有附件
        QueryWrapper<OtherFile> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(OtherFile::getCorrelationId, contract.getId()).eq(OtherFile::getStreamType, 2);
        List<OtherFile> list = otherFileMapper.selectList(wrapper);
        if (list.size() != 0) {
            for (OtherFile otherFile : list) {
                otherFileMapper.deleteById(otherFile);
            }
        }
        List<OtherFile> otherFiles = contract.getOtherFiles();
        for (OtherFile otherFile : otherFiles) {
            otherFile.setCreateTime(DateUtil.date());
            otherFile.setCorrelationId(one.getId());
            otherFile.setStreamType(2);
            otherFileMapper.insert(otherFile);
        }
        //条款
        if (contract.getArticleList() != null) {
            ContractArticleSon son = casMapper.selectOne(new QueryWrapper<ContractArticleSon>().lambda()
                    .eq(ContractArticleSon::getContractId, contract.getId()));
            if (son != null) {
                casMapper.deleteById(son);
            }
            ContractArticle articleList = contract.getArticleList();
            ContractArticleSon articleSon = new ContractArticleSon();
            articleSon.setContractId(contract.getId());
            articleSon.setArticleId(articleList.getId());
            casMapper.insert(articleSon);
            contract.setLessorArticleTitle(articleList.getArticleTitle());
            contract.setLessorArticle(articleList.getArticleText());
        }
        contract.setQuotesId(contract.getQuotesData().getId());
        mapper.updateById(contract);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void  deleteContract(List<Integer> ids) {
        for (Integer id : ids) {
            Contract contract = mapper.selectById(id);
            if (contract == null) {
                throw new CustomException(ResultCode.CONTRACT_DATA_NOT_FOUND);
            }
            //修改报价 is_contract 为否
            LambdaQueryWrapper<Quotes> eq = new QueryWrapper<Quotes>()
                    .lambda().eq(Quotes::getId, contract.getQuotesId());
            Quotes quotes = new Quotes();
            quotes.setIsContract(0);
            quotesMapper.update(quotes,eq);
            //删除合同
            contract.setDeleted(1);
            customerService.deleteThorough(2,id);
            mapper.updateById(contract);
            //生产单
            QueryWrapper<Produce> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(Produce::getContractId,id).ne(Produce::getStatus,4);
            Produce produce = new Produce();
            produce.setStatus(4);
            produceMapper.update(produce,wrapper);
            //送货
            QueryWrapper<Deliver> deliverWrapper = new QueryWrapper<>();
            deliverWrapper.lambda().eq(Deliver::getContractId,id).ne(Deliver::getStatus,4);
            Deliver deliver = new Deliver();
            deliver.setStatus(4);
            deliverMapper.update(deliver,deliverWrapper);
            //计划回款
            QueryWrapper<PlanCollect> planWrapper = new QueryWrapper<>();
            planWrapper.lambda().eq(PlanCollect::getContractId,id).eq(PlanCollect::getDeleted,0);
            planCollectMapper.delete(planWrapper);
        }
    }

    @Override
    public List<Contract> conditionList(Integer type, Integer status, String starTime, String endTime) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        LambdaQueryWrapper<Contract> lamb = new LambdaQueryWrapper<>();
        if (StrUtil.isNotEmpty(starTime) || StrUtil.isNotEmpty(endTime)) {
            if (StrUtil.isEmpty(endTime)) {
                endTime = DateUtil.date().toString();
            }
            if (StrUtil.isEmpty(starTime)) {
                starTime = "1999-01-01";
            }
            try {
                df.parse(starTime);
                df.parse(endTime);
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
            lamb.ge(StrUtil.isNotBlank(starTime), Contract::getCreateTime, starTime)
                    .le(StrUtil.isNotBlank(endTime), Contract::getCreateTime, endTime);
            return mapper.selectList(lamb);
        }
        if (type != null || status != null) {
            lamb.eq(Contract::getType, type).or().eq(Contract::getStatus, status);
            return mapper.selectList(lamb);
        }
        return mapper.selectList(null);
    }


    @Override
    public Contract selectByContractId(Integer id) {
        Contract contract = mapper.selectById(id);
        if(contract == null){
            return new Contract();
        }
        Admin admin = adminMapper.selectById(contract.getAdminId());
        contract.setUsername(admin.getUsername());
        //查附件
        List<OtherFile> list = otherFileMapper.selectList(new QueryWrapper<OtherFile>().lambda()
                .eq(OtherFile::getStreamType, 2).eq(OtherFile::getCorrelationId, id));
        if (list == null){
            list = new ArrayList<>();
        }
        contract.setOtherFiles(list);
        //查条款
        ContractArticle articles = articleMapper.selectArticleList(id);
        if (articles != null) {
            contract.setArticleList(articles);
            contract.setLessorArticleTitle(articles.getArticleTitle());
        }
        //查报价
        Quotes quotes = quotesService.selectDetailById(contract.getQuotesId());
        contract.setQuotesData(quotes);
        //客户信息
        Customer customer = customerMapper.selectById(contract.getCustomerId());
        contract.setCustomerData(customer);
        //合同设置
        ContractFit contractFit = fitMapper.selectOne(new QueryWrapper<ContractFit>().lambda()
                .eq(ContractFit::getPartyBName, contract.getPartyBName()));
        contract.setContractFit(contractFit);
        return contract;
    }

    @Override
    public List<ScheduleTime> getContractSchedule(Integer id, String code){
        List<ScheduleTime> resultList = new ArrayList<>();
        QueryWrapper<Contract> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(id != null, Contract::getId,id).or()
                .eq(StrUtil.isNotBlank(code), Contract::getNum, code);
        Contract contract = mapper.selectOne(wrapper);
        if(contract!=null){
            //合同创建
            ScheduleTime scheduleTime = new ScheduleTime();
            scheduleTime.setTitle(contract.getName() + "创建");
            scheduleTime.setTime(contract.getCreateTime());
            resultList.add(scheduleTime);
            //合同审核
            Examine examine = examineMapper.selectOne(new QueryWrapper<Examine>().lambda()
                    .eq(Examine::getCorrelationId, contract.getId())
                    .eq(Examine::getStreamType, 2)
                    .eq(Examine::getExamineType,0)
                    .eq(Examine::getStatus,1)
                    .orderByDesc(Examine::getId).last(" limit 1"));
            if(examine != null){
                ScheduleTime scheduleTime1  = new ScheduleTime();
                scheduleTime1.setTitle(contract.getName() + "已审核");
                //添加审核时间
                scheduleTime1.setTime(examine.getCreateTime());
                resultList.add(scheduleTime1);
            }
            // 生产单据
            Produce produce = produceMapper.selectOne(new QueryWrapper<Produce>().lambda()
                    .eq(Produce::getContractId, contract.getId())
                    .eq(Produce::getStatus,1)
                    .eq(Produce::getSource,0));
            if(produce != null){
                ScheduleTime scheduleTime2  = new ScheduleTime();
                scheduleTime2.setTitle(contract.getName() + "创建生产单");
                scheduleTime2.setTime(produce.getCreateTime());
                resultList.add(scheduleTime2);

                // 排产
                List<ProduceScheduling> produceSchedulings = produceSchedulingMapper.selectListByProduceId(produce.getId());

                produceSchedulings.forEach(produceScheduling -> {
//                    QueryWrapper<SchedulingSon> wrapper1 = new QueryWrapper<>();
//                    wrapper1.lambda()
//                            .eq(SchedulingSon::getSchedulingId, produceScheduling.getId())
//                            .eq(SchedulingSon::getProduceId,produce.getId());
                    List<SchedulingSon> schedulingSonList = schedulingSonMapper.getListBySchedulingId(produceScheduling.getId(),produce.getId(),null);
                    if(produceScheduling.getStartTime()!=null){
                        schedulingSonList.forEach(  schedulingSon -> {
                            ScheduleTime scheduleTime4  = new ScheduleTime();
                            scheduleTime4.setTitle(contract.getName() + "中【" + schedulingSon.getProductName() + "】开始生产,排产数量：" + schedulingSon.getSchedulingNum());
                            scheduleTime4.setTime(produceScheduling.getStartTime());
                            resultList.add(scheduleTime4);
                        });
                    }
                    if(produceScheduling.getEndTime()!=null){
                        schedulingSonList.forEach(schedulingSon -> {
                            ScheduleTime scheduleTime5  = new ScheduleTime();
                            scheduleTime5.setTitle(contract.getName() + "中【" + schedulingSon.getProductName() + "】生产结束,生产数量：" + schedulingSon.getSchedulingNum());
                            scheduleTime5.setTime(produceScheduling.getEndTime());
                            resultList.add(scheduleTime5);
                        });
                    }
                });
                //生产单已完成时间轴
                if(produce.getType() == 2){
                    ScheduleTime scheduleTime3  = new ScheduleTime();
                    scheduleTime3.setTitle(contract.getName() + "生产单已完成");
                    scheduleTime3.setTime(produce.getUpdateTime());
                    resultList.add(scheduleTime3);
                }

                List<Deliver> deliverList = deliverMapper.selectList(new QueryWrapper<Deliver>().lambda()
                        .eq(Deliver::getProduceId, produce.getId())
                        .eq(Deliver::getSource,0));

                if(deliverList.size()!=0){
                    deliverList.forEach(deliver -> {
                        if(deliver.getCreateTime()!= null ){
                            ScheduleTime scheduleTime6  = new ScheduleTime();
                            scheduleTime6.setTitle(contract.getName() + "发货中");
                            scheduleTime6.setTime(deliver.getCreateTime());
                            resultList.add(scheduleTime6);
                        }
                        if(deliver.getDeliveryTime() != null){
                            ScheduleTime scheduleTime7  = new ScheduleTime();
                            scheduleTime7.setTitle(contract.getName() + "确定收货");
                            scheduleTime7.setTime(deliver.getDeliveryTime());
                            resultList.add(scheduleTime7);
                        }
                    });
                }

                //退货
                QueryWrapper<Rejected> wrapper1 = new QueryWrapper<>();
                wrapper1.lambda()
                        .eq(Rejected::getProduceId,produce.getId())
                        .eq(Rejected::getDeleted, 0)
                        .eq(Rejected::getStatus,1);
                List<Rejected> rejecteds = rejectedMapper.selectList(wrapper1);
                if (rejecteds.size() != 0){
                    rejecteds.forEach(rejected -> {
                        ScheduleTime scheduleTime8 = new ScheduleTime();
                        scheduleTime8.setTitle(contract.getName()+"的【"+rejected.getName()+"】退货单：已创建");
                        scheduleTime8.setTime(rejected.getCreateTime());
                        resultList.add(scheduleTime8);
                        if (rejected.getRejectedState() == 1){
                            ScheduleTime scheduleTime16 = new ScheduleTime();
                            scheduleTime16.setTitle(contract.getName()+"的【"+rejected.getName()+"】退货单：已完成");
                            scheduleTime16.setTime(rejected.getUpdateTime());
                            resultList.add(scheduleTime16);
                        }
                        //查看重做的生产单
                        List<Produce> rejectedProduces = produceMapper.selectList(new QueryWrapper<Produce>().lambda()
                                .eq(Produce::getRejectedId, rejected.getId())
                                .eq(Produce::getStatus,1)
                                .eq(Produce::getSource,1));
                        rejectedProduces.forEach(produce1 -> {
                            if (produce1 != null){
                                ScheduleTime scheduleTime9 = new ScheduleTime();
                                scheduleTime9.setTitle("【"+rejected.getName()+"】的生产单"+"【"+produce1.getName()+"】"+"已创建");
                                scheduleTime9.setTime(rejected.getCreateTime());
                                resultList.add(scheduleTime9);
                            }
                            if(produce1.getType() == 2){
                                ScheduleTime scheduleTime10 = new ScheduleTime();
                                scheduleTime10.setTitle("【"+rejected.getName()+"】的生产单"+"【"+produce1.getName()+"】"+"生产完成");
                                scheduleTime10.setTime(rejected.getCreateTime());
                                resultList.add(scheduleTime10);
                            }
                            //重做的发货
                            List<Deliver> deliverList1 = deliverMapper.selectList(new QueryWrapper<Deliver>()
                                    .lambda().eq(Deliver::getProduceId, produce1.getId()));

                            if(deliverList1.size()!=0){
                                deliverList1.forEach(deliver -> {
                                    if(deliver.getCreateTime()!= null ){
                                        ScheduleTime scheduleTime11  = new ScheduleTime();
                                        scheduleTime11.setTitle(produce1.getName() + "发货中");
                                        scheduleTime11.setTime(deliver.getCreateTime());
                                        resultList.add(scheduleTime11);
                                    }
                                    if(deliver.getDeliveryTime() != null){
                                        ScheduleTime scheduleTime12  = new ScheduleTime();
                                        scheduleTime12.setTitle(produce1.getName() + "确定收货");
                                        scheduleTime12.setTime(deliver.getDeliveryTime());
                                        resultList.add(scheduleTime12);
                                    }
                                });
                            }
                        });

                        //维修
                        QueryWrapper<Repair> wrapper2 = new QueryWrapper<>();
                        wrapper2
                                .lambda().eq(Repair::getRejectId,rejected.getId());
                        List<Repair> repairs = repairMapper.selectList(wrapper2);
                        if (repairs.size() != 0){
                            repairs.forEach(repair -> {
                                if(repair.getCreateTime() != null){
                                    ScheduleTime scheduleTime12 = new ScheduleTime();
                                    scheduleTime12.setTitle("【"+rejected.getName()+"】的【"+repair.getRepairName()+"】维修单：已创建");
                                    scheduleTime12.setTime(repair.getCreateTime());
                                    resultList.add(scheduleTime12);                                }
                                if(repair.getUpdateTime() != null){
                                    ScheduleTime scheduleTime13 = new ScheduleTime();
                                    scheduleTime13.setTitle("【"+rejected.getName()+"】的【"+repair.getRepairName()+"】维修单：维修完成");
                                    scheduleTime13.setTime(repair.getCreateTime());
                                    resultList.add(scheduleTime13);
                                }
                            });
                        }
                        //退货的送货
                        List<Deliver> deliverList1 = deliverMapper.selectList(new QueryWrapper<Deliver>().lambda()
                                .eq(Deliver::getRejectedId, rejected.getId())
                                .eq(Deliver::getSource,1));
                        deliverList1.forEach(deliver -> {
                            if (deliver.getCreateTime() != null){
                                ScheduleTime scheduleTime14 = new ScheduleTime();
                                scheduleTime14.setTitle("【"+rejected.getName()+"】的【"+deliver.getDeliveryName()+"】送货单：开始送货");
                                scheduleTime14.setTime(deliver.getCreateTime());
                                resultList.add(scheduleTime14);
                            }
                            if (deliver.getUpdateTime() != null){
                                ScheduleTime scheduleTime15 = new ScheduleTime();
                                scheduleTime15.setTitle("【"+rejected.getName()+"】的【"+deliver.getDeliveryName()+"】送货单：送货完成");
                                scheduleTime15.setTime(deliver.getUpdateTime());
                                resultList.add(scheduleTime15);
                            }
                        });
                    });
                }
            }
        }
        return resultList.stream().sorted(Comparator.comparing(ScheduleTime::getTime)).collect(Collectors.toList());
        //return null;
    }


    @Override
    public Contract selectByCustomerId(Integer id) {
        Contract contract = mapper.selectOne(new QueryWrapper<Contract>().lambda().eq(Contract::getCustomerId, id));
        return contract;
    }

    @Override
    public Map<String, Object> businessStatistics() {
        Map<String, Object> map = new HashMap<>();
        QueryWrapper<Contract> wrapper = new QueryWrapper<>();
        // 合同 年数量
        wrapper.eq("deleted", 0)
                .eq("status", 1);
                //.apply("left(order_time, 4) = left(Now(),4)");
        Long contractYearNum = mapper.selectContractCount(wrapper);
        map.put("contractYearNum",contractYearNum);
        // 合同 月数量
        wrapper.clear();
        wrapper.eq("deleted", 0)
                .eq("status", 1)
                .apply("left(order_time, 7) = left(Now(),7)");
        Long contractMonthNum = mapper.selectContractCount(wrapper);
        map.put("contractMonthNum", contractMonthNum);
        // 合同 年金额
        Double contractTotalMoney = mapper.selectYearContractMoney();
        map.put("contractYearMoney", contractTotalMoney);
        // 合同 月金额
        Double countMonthAddMoney = mapper.selectMonthContractMoney();
        map.put("contractMonthMoney",countMonthAddMoney);

        QueryWrapper<Customer> wrapper1 = new QueryWrapper<>();
        // 客户 年数量
        wrapper1.eq("status", 1);
                //.apply("left(create_time,4) = left(Now(),4)");
        Long customerTotalNum = customerMapper.selectCustomerCount(wrapper1);
        map.put("customerYearNum", customerTotalNum);
        // 客户 月数量
        wrapper1.clear();
        wrapper1.eq("status", 1)
                .apply("left(create_time,7) = left(Now(),7)");
        Long customerMonthAddNum = customerMapper.selectCustomerCount(wrapper1);
        map.put("customerMonthNum", customerMonthAddNum);
        return map;
    }


    @Override
    public String selectCustomerAddressByContractId(Integer contractId){
        Contract contract = mapper.selectById(contractId);
        Quotes quotes = quotesMapper.selectById(contract.getQuotesId());
        Customer customer = customerMapper.selectById(quotes.getCustomerId());
        return customer.getAddress();
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void antiAudit(Integer correlationId){
        QueryWrapper<Produce> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(Produce::getContractId,correlationId)
                .ne(Produce::getType,0);
        List<Produce> produces = produceMapper.selectList(wrapper);
        if (produces.size() != 0){
            throw new CustomException(ResultCode.PRODUCE_IS_EXIST);
        }
        Contract contract = new Contract();
        contract.setStatus(0);
        mapper.update(contract,new QueryWrapper<Contract>().lambda()
                .eq(Contract::getId,correlationId));
        //生产单
        wrapper.clear();
        wrapper.lambda().eq(Produce::getContractId,correlationId).ne(Produce::getStatus,4);
        Produce produce = new Produce();
        produce.setStatus(4);
        produceMapper.update(produce,wrapper);
        //送货
        QueryWrapper<Deliver> deliverWrapper = new QueryWrapper<>();
        deliverWrapper.lambda().eq(Deliver::getContractId,correlationId).ne(Deliver::getStatus,4);
        Deliver deliver = new Deliver();
        deliver.setStatus(4);
        deliverMapper.update(deliver,deliverWrapper);
        //计划回款
        QueryWrapper<PlanCollect> planWrapper = new QueryWrapper<>();
        planWrapper.lambda().eq(PlanCollect::getContractId,correlationId).eq(PlanCollect::getDeleted,0);
        planCollectMapper.delete(planWrapper);
        //回款
//        QueryWrapper<CustomerPayment> paymentWrapper = new QueryWrapper<>();
//        paymentWrapper.lambda().eq(CustomerPayment::getContractId,correlationId).ne(CustomerPayment::getStatus,4);
//        CustomerPayment customerPayment = new CustomerPayment();
//        customerPayment.setStatus(4);
//        paymentMapper.update(customerPayment,paymentWrapper);
    }

    @Override
    public void supplementContract(Contract contract) {
        Contract contract1 = mapper.selectById(contract.getId());
        if (contract1.getStatus() != 1){
            throw new CustomException(ResultCode.CONTRACT_IS_UNABLE_SUPPLEMENT);
        }
        contract.setUpdateTime(DateUtil.date());
        mapper.updateById(contract);
        if (contract1.getPaymentMethod() == 3){
            PlanCollect planCollect = planCollectMapper.selectOne(new QueryWrapper<PlanCollect>()
                    .lambda()
                    .eq(PlanCollect::getContractId, contract.getId()));
            planCollect.setPlanMoney( planCollect.getPlanMoney() + contract.getSupplementMoney() );
            planCollectMapper.updateById(planCollect);
        }
    }

    @Override
    public void obsoleteById(Integer id){
        QueryWrapper<Contract> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Contract::getId, id);
        Contract contract = new Contract();
        contract.setStatus(3);
        mapper.update(contract,wrapper);
    }
}
